package com.rgzn.fzxj.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.rgzn.fzxj.service.TokenService;
import com.rgzn.fzxj.config.WechatConfig;
import com.rgzn.fzxj.domain.Wechat;
import com.rgzn.fzxj.enums.MsgType;
import com.rgzn.fzxj.util.WechatUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.*;

@Controller
public class WechatController {

    private static Logger logger = LoggerFactory.getLogger(WechatController.class);

    ExecutorService executors = Executors.newFixedThreadPool(10);

    private static ConcurrentHashMap<String, Wechat> wechatMap = new ConcurrentHashMap<>();

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private TokenService tokenService;

    @GetMapping("/wechat")
    @ResponseBody
    public void checkToken(@RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("echostr") String echostr,
                           HttpServletResponse response) {
        // 验证Token
        boolean valid = WechatUtils.checkToken(signature, timestamp, nonce);
        if (valid) {
            try {
                // 验证成功，返回echostr
                response.getWriter().print(echostr);
                logger.info("微信Token验证成功，返回echostr: {}", echostr);
            } catch (Exception e) {
                logger.error("响应echostr时发生异常", e);
            }
        } else {
            // 验证失败，记录日志且不返回内容
            logger.error("微信Token验证失败，参数：signature={}, timestamp={}, nonce={}",
                    signature, timestamp, nonce);
        }

    }

    @PostMapping(value = "/wechat", produces = "application/xml;charset=UTF-8")
    public void sendIngMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        String xmlData = readRequestBody(request);
        Wechat wechat = WechatUtils.parseXml2Object(xmlData.toString(), Wechat.class);
        logger.info("接受微信消息：{}", JSON.toJSONString(wechat));
        Wechat currentWechat = wechatMap.get(wechat.getMsgId());
        if (null == currentWechat) {
            wechatMap.put(wechat.getMsgId(), wechat);
            String responseContentWechat = handleWechatMessage(wechat);
            String responseContent = createResponseXml(wechat, responseContentWechat);
            response.getWriter().write(responseContent);
        }
    }

    private String handleTextMessage(Wechat wechat) {
        logger.info("文本类型消息: {}", wechat.getMsgType());
        // 异步处理业务逻辑
        CompletableFuture.runAsync(() -> asyncSending(wechat), executors);
        return "";
    }

    private String handleImageMessage(Wechat wechat) {
        logger.info("图片类型消息: {}", wechat.getMsgType());
        return "您发的图片中如果有二维码需要您使用微信扫描我建议您不要去盲目扫描，图片中的二维码可能包含诈骗信息，造成您的财产损失，如需扫描请谨慎资金被盗~";
    }

    private String handleVoiceMessage(Wechat wechat) {
        logger.info("语音类型消息: {}", wechat.getMsgType());
        // 异步处理业务逻辑
        CompletableFuture.runAsync(() -> asyncSendingVoice(wechat), executors);
        return "";
    }

    private void asyncSendingVoice(Wechat wechat) {
        try {
            String amrToMp3TmePath = tokenService.getMediaIdMp3Path(wechat.getMediaId());
            String voiceContent = tokenService.getVoiceText(amrToMp3TmePath);
            wechat.setContent(voiceContent);
            logger.info("语音转文字内容：{}", voiceContent);
            sendAgentRequest(wechat, voiceContent);
        } catch (Exception e) {
            logger.error("异步发送语音消息失败", e);
        }
    }

    private String handleVideoMessage(Wechat wechat) {
        logger.info("视频类型消息: {}", wechat.getMsgType());
        return "我还在学习该消息类型的识别，暂不支持回复哦。如果你有问题，可以用文字和我进行交流~";
    }

    public String createResponseXml(Wechat wechat, String content) {
        return "<xml>" +
                "<ToUserName><![CDATA[" + wechat.getFromUserName() + "]]></ToUserName>" +
                "<FromUserName><![CDATA[" + wechat.getToUserName() + "]]></FromUserName>" +
                "<CreateTime>" + System.currentTimeMillis() + "</CreateTime>" +
                "<MsgType><![CDATA[text]]></MsgType>" +
                "<Content><![CDATA[" + content + "]]></Content>" +
                "</xml>";
    }

    public void asyncSending(Wechat wechat) {
        try {
            sendAgentRequest(wechat, wechat.getContent());
        } catch (InterruptedException e) {
            logger.error("异步发送消息失败", e);
        }
    }

    private void sendAgentRequest(Wechat wechat, String content) throws InterruptedException {
        boolean sendingClassificationOfIssuesFlag = tokenService.sendingClassificationOfIssues(wechat.getFromUserName(), content);
        if (sendingClassificationOfIssuesFlag) {
            logger.error("包含指定词汇：{}", content);
            return;
        }
        String url = wechatConfig.getAgentUrl();
        Map<String, Object> params = new HashMap<>();
        params.put("inputs", new Object());
        params.put("query", content);
        params.put("response_mode", "blocking");
        params.put("user", wechat.getToUserName());
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String responseContent = postForEntity(url, params);
        stopWatch.stop();
        logger.info("智能体回复耗时: {}", stopWatch.getTotalTimeSeconds());
        logger.info("智能体回复内容: {}", responseContent);
        tokenService.sending(wechat.getFromUserName(), StrUtil.utf8Str(responseContent));
        tokenService.sendingQcImage(wechat.getFromUserName(), content);
    }


    public String postForEntity(String url, Map<String, Object> requestObj) throws InterruptedException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("Authorization", wechatConfig.getAgentAuthorization());
        HttpEntity<String> requestEntity = new HttpEntity<>(JSON.toJSONString(requestObj), headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(response.getBody());
        return jsonObject.getString("answer");
    }


    private String readRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder xmlData = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                xmlData.append(line);
            }
        }
        return xmlData.toString();
    }

    private String handleWechatMessage(Wechat wechat) {
        return switch (MsgType.valueOf(wechat.getMsgType().toUpperCase())) {
            case TEXT -> handleTextMessage(wechat);
            case IMAGE -> handleImageMessage(wechat);
            case VOICE -> handleVoiceMessage(wechat);
            case VIDEO -> handleVideoMessage(wechat);
            default -> "Unknown message type";
        };
    }
}
